package top.suyarong.ftbqsync.utils;

import org.bukkit.entity.Player;
import top.suyarong.ftbqsync.FTBQSync;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class FTBLibUtil {

    private static final LogUtil log = LogUtil.getInstance();

    private static final FTBQSync plugin = FTBQSync.getInstance();

    private final static Class<?> UNIVERSE;

    private final static Method UNIVERSE_GET_PLAYER;

    public final static Field FTB_TEAM;

    private final static Constructor<?> FORGE_PLAYER_LOGGED_IN_EVENT_CONSTRUCTOR;

    private final static Constructor<?> FORGE_TEAM_CREATED_EVENT_CONSTRUCTOR;

    private final static Class<?> EVENT_BASE;

    private final static Method EVENT_BASE_POST;

    private static Object universeInstance = null;

    public static final String UTIL_NAME = "FTBLibUtil ===> {0} 载入完成";


    static {

        UNIVERSE = ReflectionUtil.getClass("com.feed_the_beast.ftblib.lib.data.Universe");
        log.debug(plugin, UTIL_NAME, UNIVERSE.getName());

        UNIVERSE_GET_PLAYER = ReflectionUtil.getSingleParamMethod(UNIVERSE, "getPlayer", NMSUtil.CLAZZ_ENTITY_PLAYER_MP.getSuperclass());
        log.debug(plugin, UTIL_NAME, UNIVERSE_GET_PLAYER.getDeclaringClass().getName() + "." + UNIVERSE_GET_PLAYER.getName() + "()");

        FTB_TEAM = ReflectionUtil.getClassField(UNIVERSE_GET_PLAYER.getReturnType(), "team");
        log.debug(plugin, UTIL_NAME, FTB_TEAM.getDeclaringClass().getName() + "." + FTB_TEAM.getName() + "()");

        FORGE_PLAYER_LOGGED_IN_EVENT_CONSTRUCTOR = ReflectionUtil
                .getSingleParamConstructor(ReflectionUtil
                        .getClass("com.feed_the_beast.ftblib.events.player.ForgePlayerLoggedInEvent"), UNIVERSE_GET_PLAYER.getReturnType());
        log.debug(plugin, UTIL_NAME, FORGE_PLAYER_LOGGED_IN_EVENT_CONSTRUCTOR.getName());

        FORGE_TEAM_CREATED_EVENT_CONSTRUCTOR = ReflectionUtil
                .getSingleParamConstructor(ReflectionUtil
                        .getClass("com.feed_the_beast.ftblib.events.team.ForgeTeamCreatedEvent"), FTB_TEAM.getType());
        log.debug(plugin, UTIL_NAME, FORGE_TEAM_CREATED_EVENT_CONSTRUCTOR.getName());

        EVENT_BASE = ReflectionUtil.getClass("com.feed_the_beast.ftblib.lib.EventBase");
        log.debug(plugin, UTIL_NAME, EVENT_BASE.getName());

        EVENT_BASE_POST = ReflectionUtil.getUnknownMethod(EVENT_BASE, "post");
        log.debug(plugin, UTIL_NAME, EVENT_BASE_POST.getDeclaringClass().getName() + "." + EVENT_BASE_POST.getName() + "()");

    }

    public static void postLogin(Player player) {
        Object forgePlayer = getForgePlayer(player);
        if (forgePlayer == null) return;
        ReflectionUtil.invokeMethod(EVENT_BASE_POST, ReflectionUtil.newInstanceByConstructor(FORGE_PLAYER_LOGGED_IN_EVENT_CONSTRUCTOR, forgePlayer));
    }

    public static void postTeamCreate(Player player) {
        Object playerTeam = getPlayerTeam(player);
        if (playerTeam == null) return;
        ReflectionUtil.invokeMethod(EVENT_BASE_POST, ReflectionUtil.newInstanceByConstructor(FORGE_TEAM_CREATED_EVENT_CONSTRUCTOR, playerTeam));
    }

    public static Object getUniverseInstance() {
        if (universeInstance == null) universeInstance = ReflectionUtil.getStaticFieldValue(UNIVERSE, "INSTANCE");
        return universeInstance;
    }

    public static Object getPlayerTeam(Player player) {
        Object forgePlayer = getForgePlayer(player);
        return ReflectionUtil.getInstanceFieldValue(forgePlayer, FTB_TEAM);
    }

    public static Object getForgePlayer(Player player) {
        return ReflectionUtil.invokeMethod(UNIVERSE_GET_PLAYER, getUniverseInstance(), NMSUtil.getNMSPlayer(player));
    }

    public static void init() {
        log.debug(plugin, "&eFTBLibUtil初始化完毕");
    }

}
